package com.markbuikema.juliana32;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.util.Base64;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SearchView;
import android.widget.SearchView.OnCloseListener;
import android.widget.SearchView.OnQueryTextListener;
import android.widget.ShareActionProvider;
import android.widget.TextView;
import at.markushi.ui.ActionView;
import at.markushi.ui.action.BackAction;
import at.markushi.ui.action.CloseAction;
import at.markushi.ui.action.DrawerAction;

import com.facebook.Session;
import com.facebook.Session.StatusCallback;
import com.facebook.SessionState;
import com.markbuikema.juliana32.adapter.DrawerAdapter;
import com.markbuikema.juliana32.fragment.AgendaFragment;
import com.markbuikema.juliana32.fragment.NieuwsFragment;
import com.markbuikema.juliana32.fragment.TeamFragment;
import com.markbuikema.juliana32.model.teams.Team;
import com.markbuikema.juliana32.ui.Page;
import com.markbuikema.juliana32.util.Constants;
import com.markbuikema.juliana32.util.DataManager;
import com.markbuikema.juliana32.util.DataManager.DataLoadedCallback;
import com.markbuikema.juliana32.util.facebook.FacebookManager;
import com.readystatesoftware.systembartint.SystemBarTintManager;

public class MainActivity extends FragmentActivity {

	private FacebookManager facebookHelper;

	private ActionView actionView;
	private DrawerLayout drawerLayout;
	private DrawerAdapter drawerAdapter;
	private FrameLayout drawer;
	private ListView drawerList;
	private ProgressBar drawerLoader;

	private Fragment activeFragment;
	private Fragment nextActiveFragment;
	private boolean changeFragment;
	private Handler handler;
	private Page page;

	private boolean shouldHideMenu = false;
	private boolean nieuwsDetail;
	private int currentTeamIndex = -1;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		logHashKey();
		facebookHelper = FacebookManager.getInstance().onCreate(savedInstanceState, this, statusCallback);

		SystemBarTintManager tintManager = new SystemBarTintManager(this);
		tintManager.setStatusBarTintEnabled(true);
		tintManager.setStatusBarTintResource(R.color.juliana_blue_transparent);

		// Intent service = new Intent(this, GameNotificationService.class);
		// service.putExtra("gameid", "test!");
		// startService(service); TODO FIX SERVICE!!!!

		handler = new Handler();

		actionView = (ActionView) getActionBar().getCustomView().findViewById(R.id.drawer_button);
		drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
		drawer = (FrameLayout) findViewById(R.id.left_drawer);
		drawerList = (ListView) drawer.findViewById(R.id.drawer);
		drawerLoader = (ProgressBar) drawer.findViewById(R.id.drawer_loader);

		actionView.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (nieuwsDetail) {
					NieuwsFragment nf = (NieuwsFragment) getSupportFragmentManager().findFragmentByTag(NieuwsFragment.class.getName());
					if (nf != null) {
						if (nf.isNieuwsDetail()) {
							nf.hideNieuwsDetail();
							onNieuwsDetailClosed();
							return;
						}

					}
				}
				if (!drawerLayout.isDrawerOpen(Gravity.START)) {
					actionView.setAction(new BackAction());
					drawerLayout.openDrawer(Gravity.START);
				} else {
					drawerLayout.closeDrawer(Gravity.START);
				}
			}
		});

		drawerList.setOnItemClickListener(onDrawerItemClicked);

		drawerLayout.setDrawerListener(new DrawerListener() {
			private float previousOffset = 0f;

			@Override
			public void onDrawerClosed(View drawerView) {

				String tag = null;
				switch (page) {
				case AGENDA:
					tag = AgendaFragment.class.getName();
					break;
				case NIEUWS:
					tag = NieuwsFragment.class.getName();
					break;
				case TEAMS:
					tag = TeamFragment.class.getName() + currentTeamIndex;
					break;
				}

				if (changeFragment) {
					getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).replace(R.id.content_frame, nextActiveFragment, tag).commit();

					afterPageChanged();
				}
			}

			@Override
			public void onDrawerSlide(View drawerView, float slideOffset) {
				if (slideOffset > previousOffset && !shouldHideMenu) {
					shouldHideMenu = true;
					invalidateOptionsMenu();
				} else if (previousOffset > slideOffset && slideOffset < 0.5f && shouldHideMenu) {
					shouldHideMenu = false;
					invalidateOptionsMenu();
				}
				previousOffset = slideOffset;

				actionView.setAnimationProgress(slideOffset);

				drawerList.setAlpha(.5f + .5f * slideOffset);
			}

			@Override
			public void onDrawerOpened(View arg0) {

			}

			@Override
			public void onDrawerStateChanged(int arg0) {

			}
		});
		drawerLayout.setScrimColor(getResources().getColor(R.color.juliana_blue_transparent));
		drawerAdapter = new DrawerAdapter(this);
		drawerList.setAdapter(drawerAdapter);

		activeFragment = new NieuwsFragment();
		if (getSupportFragmentManager().findFragmentByTag(NieuwsFragment.class.getName()) == null)
			getSupportFragmentManager().beginTransaction().add(R.id.content_frame, activeFragment, NieuwsFragment.class.getName()).commit();
		DataManager.getInstance().loadTeams(new DataLoadedCallback() {

			@Override
			public void onDataLoaded(List<?> data) {
				drawerAdapter.notifyDataSetChanged();
				drawerLoader.setVisibility(View.GONE);
			}
		});
		page = Page.NIEUWS;

	}

	public void beforePageChanged(Page page, final int index) {

		final int indexOffset = drawerAdapter.getCount() - DataManager.getInstance().getTeams().size();

		if ((page == this.page && page != Page.TEAMS) || index - indexOffset == this.currentTeamIndex) {
			changeFragment = false;
			handler.postDelayed(new Runnable() {

				@Override
				public void run() {
					drawerLayout.closeDrawer(drawer);
				}
			}, 150);
			return;
		}

		getSupportFragmentManager().beginTransaction().remove(activeFragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit();

		this.page = page;

		switch (page) {
		case NIEUWS:
			NieuwsFragment nieuws = (NieuwsFragment) getSupportFragmentManager().findFragmentByTag(NieuwsFragment.class.getName());
			if (nieuws == null)
				nextActiveFragment = new NieuwsFragment();
			else
				nextActiveFragment = nieuws;
			break;
		case AGENDA:
			AgendaFragment agenda = (AgendaFragment) getSupportFragmentManager().findFragmentByTag(AgendaFragment.class.getName());
			if (agenda == null) {
				nextActiveFragment = new AgendaFragment();
			} else {
				nextActiveFragment = agenda;
			}
			break;
		case TEAMS:
			currentTeamIndex = (index - indexOffset);

			TeamFragment teams = (TeamFragment) getSupportFragmentManager().findFragmentByTag(TeamFragment.class.getName() + currentTeamIndex);
			if (teams == null) {

				TeamFragment frag = new TeamFragment();
				Bundle args = new Bundle();
				args.putInt("team_index", currentTeamIndex);
				frag.setArguments(args);

				// DataManager.getInstance().getTeams().get(currentTeamIndex).addObserver(frag);

				nextActiveFragment = frag;
			} else {
				nextActiveFragment = teams;
			}

			break;
		}

		changeFragment = true;

		handler.postDelayed(new Runnable() {

			@Override
			public void run() {
				drawerLayout.closeDrawer(drawer);
			}
		}, 150);
		drawerAdapter.setSelected(index);
	}

	public void afterPageChanged() {
		activeFragment = nextActiveFragment;
		nextActiveFragment = null;

		changeFragment = false;

		invalidateOptionsMenu();
	}

	public void onNieuwsDetailOpened() {
		Page.NIEUWS.setDetail(true);
		invalidateOptionsMenu();

		actionView.setAction(new CloseAction());
		nieuwsDetail = true;
	}

	public void onNieuwsDetailClosed() {
		Page.NIEUWS.setDetail(false);
		invalidateOptionsMenu();

		actionView.setAction(new DrawerAction());
	}

	@Override
	protected void onStart() {
		super.onStart();
		facebookHelper.onStart();
	}

	@Override
	protected void onStop() {
		super.onStop();
		facebookHelper.onStop();
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		facebookHelper.onActivityResult(this, requestCode, resultCode, data);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		if (shouldHideMenu) {
			menu.clear();
		} else {
			getMenuInflater().inflate(page.getMenuResource(), menu);

			final MenuItem search = menu.findItem(R.id.action_search);
			if (search != null) {
				SearchView searchView = (SearchView) search.getActionView();
				searchView.setOnQueryTextListener(new OnQueryTextListener() {

					@Override
					public boolean onQueryTextSubmit(String query) {
						query = query.trim();
						if (query.isEmpty()) {
							((NieuwsFragment) activeFragment).clearSearch();
							search.collapseActionView();
						} else
							((NieuwsFragment) activeFragment).search(query);
						return true;
					}

					@Override
					public boolean onQueryTextChange(String newText) {
						return true;
					}
				});
				searchView.setOnCloseListener(new OnCloseListener() {

					@Override
					public boolean onClose() {
						((NieuwsFragment) activeFragment).clearSearch();
						return true;
					}
				});
				styleSearchView(searchView);
			}

			MenuItem facebook = menu.findItem(R.id.action_check_facebook);
			if (facebook != null) {
				SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
				facebook.setChecked(prefs.getBoolean(Constants.KEY_FACEBOOK, true));
			}

			MenuItem website = menu.findItem(R.id.action_check_website);
			if (website != null) {
				SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
				website.setChecked(prefs.getBoolean(Constants.KEY_WEBSITE, true));
			}

			MenuItem share = menu.findItem(R.id.action_share);
			if (share != null) {
				ShareActionProvider sap = (ShareActionProvider) share.getActionProvider();
				Intent intent = new Intent(Intent.ACTION_SEND);
				NieuwsFragment nf = (NieuwsFragment) getSupportFragmentManager().findFragmentByTag(NieuwsFragment.class.getName());
				String title = nf.getItemTitle();
				String content = nf.getItemContent();
				intent.setType("text/plain");
				intent.putExtra(Intent.EXTRA_SUBJECT, title);
				intent.putExtra(Intent.EXTRA_TEXT, content);
				sap.setShareIntent(intent);
			}

			MenuItem favTeam = menu.findItem(R.id.action_favorites);
			if (favTeam != null) {

				Team team = DataManager.getInstance().getTeams().get(currentTeamIndex);

				SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
				Set<String> favs = prefs.getStringSet("fav_teams", null);

				boolean fav = favs != null && favs.contains(team.getId());
				favTeam.setChecked(fav);
				favTeam.setIcon(fav ? R.drawable.ic_action_rating_important : R.drawable.ic_action_rating_not_important);

			}

			MenuItem today = menu.findItem(R.id.action_go_to_today);
			if (today != null) {
				AgendaFragment af = (AgendaFragment) getSupportFragmentManager().findFragmentByTag(AgendaFragment.class.getName());

				if (af != null)
					today.setVisible(new GregorianCalendar().get(GregorianCalendar.WEEK_OF_YEAR) != af.getWeek());
			}

		}

		return true;
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

		switch (item.getItemId()) {
		case R.id.action_check_facebook:
			item.setChecked(!item.isChecked());
			prefs.edit().putBoolean(Constants.KEY_FACEBOOK, item.isChecked()).commit();
			NieuwsFragment nff = (NieuwsFragment) getSupportFragmentManager().findFragmentByTag(NieuwsFragment.class.getName());
			nff.refresh(false);
			break;
		case R.id.action_check_website:
			item.setChecked(!item.isChecked());
			prefs.edit().putBoolean(Constants.KEY_WEBSITE, item.isChecked()).commit();
			NieuwsFragment nfw = (NieuwsFragment) getSupportFragmentManager().findFragmentByTag(NieuwsFragment.class.getName());
			nfw.refresh(false);
			break;
		case R.id.action_favorites:
			item.setChecked(!item.isChecked());
			item.setIcon(item.isChecked() ? R.drawable.ic_action_rating_important : R.drawable.ic_action_rating_not_important);

			Set<String> favs = prefs.getStringSet("fav_teams", null);

			Team team = DataManager.getInstance().getTeams().get(currentTeamIndex);

			if (favs == null)
				favs = new HashSet<String>();

			if (item.isChecked()) {
				favs.add(team.getId());
			} else {
				favs.remove(team.getId());
			}

			prefs.edit().putStringSet("fav_teams", favs).commit();
			break;
		case R.id.action_go_to_today:
			AgendaFragment af = (AgendaFragment) getSupportFragmentManager().findFragmentByTag(AgendaFragment.class.getName());
			int current = new GregorianCalendar().get(GregorianCalendar.WEEK_OF_YEAR);
			af.setWeek(current);
			break;
		case android.R.id.home:
			if (nieuwsDetail) {
				nieuwsDetail = false;
				onBackPressed();
			}
			break;
		}

		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onBackPressed() {

		NieuwsFragment nf = (NieuwsFragment) getSupportFragmentManager().findFragmentByTag(NieuwsFragment.class.getName());
		if (nf != null) {
			if (nf.isNieuwsDetail()) {
				nf.hideNieuwsDetail();
				return;
			}

		}

		super.onBackPressed();
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		for (int i = 0; i < menu.size(); i++) {
			MenuItem mi = menu.getItem(i);
			String title = mi.getTitle().toString();
			Spannable newTitle = new SpannableString(title);
			newTitle.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.juliana_blue)), 0, newTitle.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			mi.setTitle(newTitle);
		}
		return true;
	}

	private OnItemClickListener onDrawerItemClicked = new OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> av, View view, int position, long l) {
			drawerList.setItemChecked(position, true);

			Page page;

			switch (position) {
			case 0:
				page = Page.NIEUWS;
				break;
			case 1:
				page = Page.AGENDA;
				break;
			default:
				page = Page.TEAMS;
			}
			beforePageChanged(page, position);
		}
	};

	private void styleSearchView(SearchView searchView) {
		int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
		View searchPlate = searchView.findViewById(searchPlateId);

		if (searchPlate != null) {
			int searchTextId = searchPlate.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
			TextView searchText = (TextView) searchPlate.findViewById(searchTextId);
			if (searchText != null) {
				searchText.setTextColor(Color.WHITE);
				searchText.setHintTextColor(Color.WHITE);
			}
		}
	}

	private StatusCallback statusCallback = new StatusCallback() {

		@Override
		public void call(Session session, SessionState state, Exception exception) {
			if (exception == null && session.isOpened()) {
				NieuwsFragment nf = (NieuwsFragment) getSupportFragmentManager().findFragmentByTag(NieuwsFragment.class.getName());
				if (nf != null && nf.isNieuwsDetail()) {
					nf.updateFacebookStatus(session);
				}
			}
		}
	};

	public void logHashKey() {
		PackageInfo info;

		try {
			info = getPackageManager().getPackageInfo("com.markbuikema.juliana32", PackageManager.GET_SIGNATURES);
			for (Signature signature : info.signatures) {
				MessageDigest md;
				md = MessageDigest.getInstance("SHA");
				md.update(signature.toByteArray());
				String something = new String(Base64.encode(md.digest(), 0));
				// String something = new
				// String(Base64.encodeBytes(md.digest()));
				// Toast.makeText(this, "HASH KEY:" + something,
				// Toast.LENGTH_LONG).show();
			}
		} catch (NameNotFoundException e1) {
		} catch (NoSuchAlgorithmException e) {
		} catch (Exception e) {
		}
		// Log.d(TAG, "Done printing hashkey");
	}
}
